import TyOverlayexLayer from './TyOverlayexLayer'
import TyFeatureLayer from './TyFeatureLayer'
import TyMarker from './TyMarker'
import TyIcon from './TyIcon'
import TyPopup from './TyPopup'
import TyLabel from './TyLabel'
import TyCoordinateConvert from './TyCoordinateConvert'
import Map from 'ol/Map'
import TileGrid from 'ol/tilegrid/TileGrid'
import {getCenter} from 'ol/extent'
import {Image as ImageLayer, Tile as TileLayer} from 'ol/layer'
import VectorLayer from 'ol/layer/Vector'
import XYZ from 'ol/source/XYZ'
import {ImageArcGISRest, Vector as VectorSource} from 'ol/source'
import View from 'ol/View'
import {OverviewMap, ScaleLine, MousePosition, defaults} from 'ol/control'
import {createEmpty, extend} from 'ol/extent'
import {get as Get} from 'ol/proj'
import $ from 'jquery'
import {createStringXY} from 'ol/coordinate'
import GeoJSON from 'ol/format/GeoJSON'
import {Style, Icon, Stroke, Fill, Text, Circle} from 'ol/style'
import heilongjiang from '@/plugin/heilongjiang'
import xianjie from '@/plugin/xianjie'
import store from '@/store'

class TyMap {
  constructor() {
    this.tiandituUrl = 'tianditu.com'
    this.gaodeUrl = 'restapi.amap.com'
    this.mapUrl = 'http://112.102.225.88:30800/arcgis/rest/services'
    this.secretKey = '04c72e847f58af0ad531a56167f238e4'
    this.gaoMapKey = '04c72e847f58af0ad531a56167f238e4'
    this.remark = 'tymap'
    this.map = undefined
    this.prefix = 'map'
    this.center = [128.864230953125,48.02542025]
    this.zoom = 6
    this.mapDataXY = store.getters && store.getters.mapDataXY
    if (this.mapDataXY.length !== 0) {
      this.center = this.mapDataXY
      if (store.getters.mapDataId === 1)
        this.zoom = 6
      else
        this.zoom = 12
    } else {
      this.center = [128.864230953125,48.02542025]
      this.zoom = 6
    }
    this.range = null
    this.overlayexLayers = {}
    this.allResolutions = [
      0.703125,
      0.3515625,
      0.17578125,
      0.087890625,
      0.0439453125,
      0.02197265625,
      0.010986328125,
      0.0054931640625,
      0.00274658203125,
      0.001373291015625,
      0.0006866455078125,
      0.00034332275390625,
      0.000171661376953125,
      8.58306884765629E-05,
      4.29153442382814E-05,
      2.1457672119140625E-05,
      1.07288360595703E-05,
      5.36441802978515E-06
    ]
    this.resolutions = [
      0.703125,
      0.3515625,
      0.17578125,
      0.087890625,
      0.0439453125,
      0.02197265625,
      0.010986328125,
      0.0054931640625,
      0.00274658203125,
      0.001373291015625,
      0.0006866455078125,
      0.00034332275390625,
      0.000171661376953125,
      8.58306884765629E-05,
      4.29153442382814E-05,
      2.1457672119140625E-05,
      1.07288360595703E-05,
      5.36441802978515E-06
    ]
    this.titleSize = [256, 256]
    this.extent = [118.02785601698666, 43.36606061645537, 136.79103352179985, 55.6497932864995]
    this.projection = new Get('EPSG:4326')
    this.origin = [-180, 90]
    this.historyView = []
    this.isAllowUpdateHistory = true
    this.maxHistory = 10
    this.historyIndex = undefined
    this.marker = null
    this.pointOption = {}
    this.beforeCallback = undefined
  }

  /* 创建一个OverlayexLayer的图层实例
  opt = {
    id,//图层ID
    map,//ol.map实例
    overlayexs，//array<Overlayex>
  }*/
  createOverlayexLayer(opt) {
    const layer = new TyOverlayexLayer(opt)
    this.overlayexLayers[opt.id] = layer
    return layer
  }

  /* 根据对象删除OverlayexLayer图层
    overlayexLayer：OverlayexLayer实例
  */
  removeOverlayexLayer(overlayexLayer) {
    if (overlayexLayer) {
      overlayexLayer.clear()
      delete this.overlayexLayers[overlayexLayer.getId()]
    }
  }

  /* 通过OverlayexLayer图层的ID删除OverlayexLayer图层
    layerId:OverlayexLayer的图层ID
  */
  removeOverlayexLayerById(layerId) {
    if (layerId !== undefined) {
      const layerex = this.overlayexLayers[layerId.toString()]
      if (layerex) {
        layerex.clear() // 在清除marker图层前，必须先销毁其子元素(Overlayex)
      }
      delete this.overlayexLayers[layerId.toString()]
    }
  }

  // 删除所有的OverlayexLayer图层
  clearOverlayexLayers() {
    for (const item in this.overlayexLayers) {
      if (item) {
        this.removeOverlayexLayer(item)
      }
    }
  }

  // 通过OverlayexLayer图层的ID，获取特定的OverlayexLayer图层
  getOverlayexLayer(id) {
    if (id !== undefined) {
      return this.overlayexLayers[id.toString()]
    } else {
      return null
    }
  }

  // 获取所有的OverlayexLayer图层
  getAllOverlayexLayer() {
    return this.overlayexLayers
  }

  // 地图相关
  getTileGrid() {
    return new TileGrid({
      tileSize: this.titleSize,
      origin: this.origin,
      extent: this.extent,
      resolutions: this.allResolutions
    })
  }

  getTdtLayer(e) {
    const oTdtRoadLayer = new TileLayer({
      title: '天地图路网',
      source: new XYZ({
        // url:'http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=' + this.secretKey,
        url: 'http://t2.' + this.tiandituUrl + '/DataServer?T=vec_c&x={x}&y={y}&l={z}&tk=' + this.secretKey,
        projection: this.projection
      })
    })
    const oTdtRoadImgLayer = new TileLayer({
      title: '天地图路网影像',
      source: new XYZ({
        url: 'http://t2.' + this.tiandituUrl + '/DataServer?T=img_c&x={x}&y={y}&l={z}&tk=' + this.secretKey,
        projection: this.projection
      })
    })
    // http://t3.tianditu.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=c&TileMatrix={z}&TileRow={y}&TileCol={x}&style=default&format=tiles
    const oTdtAnnotation = new TileLayer({
      title: '天地图文字标注',
      source: new XYZ({
        // url:'http://t0.tianditu.gov.cn/cva_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=' + this.secretKey,
        url: 'http://t3.' + this.tiandituUrl + '/DataServer?T=cva_c&x={x}&y={y}&l={z}&tk=' + this.secretKey,
        projection: this.projection
      })
    })
    const vs = new VectorLayer({
      source: new VectorSource({
        features: (new GeoJSON({featureProjection: 'EPSG:4326'})).readFeatures(heilongjiang)  //读取Geojson格式数据，只有通过这种方式才能出来！！！
      }),
      style: new Style({
        stroke: new Stroke({ //边界样式
          color: '#ff0000',
          width: 2
        }),
        fill: new Fill({
          color: 'rgb(0 0 0 / 0)'
        })
      })
    })
    // const xj = new VectorLayer({
    //   source: new VectorSource({
    //     features: (new GeoJSON({ featureProjection: 'EPSG:4326' })).readFeatures(xianjie) , //读取Geojson格式数据，只有通过这种方式才能出来！！！
    //   }),
    //   style:new Style({
    //     stroke: new Stroke({ //边界样式
    //       color: '#fff000',
    //       width: 2
    //     }),
    //   })
    // })
    if (e === 0) {
      return [oTdtRoadLayer, oTdtRoadImgLayer, oTdtAnnotation, vs]
    } else {
      return [oTdtRoadLayer, oTdtAnnotation, vs]
    }
  }

  // 将10进制转16进制，余位补0，凑成ArcServer的切片格式
  padLeft(val, num, radix) {
    const str = val.toString(radix || 10)
    return (new Array(num).join('0') + str).slice(-num)
  }

  // 初始化配置
  initConfig(option) {
    this.extent = option.extent || this.extent
    this.resolutions = option.resolutions || this.resolutions
    /*
    scales:
    407158.3943442441
    203579.19717212205
    101789.59858606102
    50894.79929303051
    25447.399646515256
    12723.699823257628
    6361.849911628814
    3180.924955814407
    1590.4624779072035
    单位：1m:米
    dpi = 96
    两者的转换关系是：scale = resolution * 96 * 39.3701（1米=39.3701英寸，1英寸=96像素(DPI=96)）
    dpi是指每英寸的像素，也就是扫描精度
    resolution = scale / 96 / 39.3701
    */
  }

  // 鹰眼
  getOverviewMapControl() {
    this.OverviewMap = new OverviewMap({
      className: 'ol-overviewmap ol-custom-overviewmap', // 鹰眼控制样式
      // 在鹰眼中加载不同的数据源图层
      // layers: [
      //   getBaseLayer()
      // ],
      layers: this.getTdtLayer(1),
      collapseLabel: '\u00BB', // 鹰眼展开时功能按钮上的标识
      label: '\u00AB', // 鹰眼控件折叠时功能按钮标识
      collapsed: false, // 初始为展开显示方式
      tipLabel: '鹰眼',
      view: new View({
        center: getCenter(this.extent),
        resolutions: this.resolutions,
        projection: this.projection,
        // extent: xiangtanExtent,
        enableRotation: false
      })
    })
    return this.OverviewMap
  }

  getLayer() {
    const layer = new TileLayer({
      source: new XYZ({
        tileGrid: this.getTileGrid(),
        url: 'http://112.102.225.88:30800/arcgis/rest/services/HLJ_QIEPIAN_180509_12C_01TouMing/MapServer/tile/{z}/{y}/{x}',
        projection: this.projection
      })
    })
    const layers2 = new ImageLayer({
      source: new ImageArcGISRest({
        ratio: 1,
        params: {},
        url: 'http://112.102.225.88:30800/arcgis/rest/services/hlj/MapServer'
      })
    })
    return [layer, layers2]
  }

  // 创建地图
  createMap(target, mapType) {
    this.map = new Map({
      target: target,
      // controls: defaults().extend([this.getOverviewMapControl()]),
      controls: defaults({
        zoom: false
      }).extend([this.getOverviewMapControl(),
        // 添加比例尺
        new ScaleLine({
          units: 'metric'
        }),
        new MousePosition({
          coordinateFormat: createStringXY(13) // 保留13位小数位
        })
      ]),
      logo: false, // 不显示logo
      layers: this.getTdtLayer(0),
      view: this.getMapView()
    })
    this.map.getLayers().item(0).setVisible(false)
  }

  // view
  getMapView() {
    return new View({
      center: this.getCenter(),
      resolutions: this.resolutions,
      projection: this.projection,
      zoomControl: true,// 地图是否可被缩放控制
      zoom: this.zoom
    })
  }

  changeMap(type) {
    this.map.getLayers().forEach((item, index) => {
      if (index <= 3) {
        switch (type) {
          case 'vectorMap':
            this.map.getLayers().item(0).setVisible(true)
            this.map.getLayers().item(1).setVisible(false)
            this.map.getLayers().item(2).setVisible(true)
            break
          case 'imageMap':
            this.map.getLayers().item(0).setVisible(false)
            this.map.getLayers().item(1).setVisible(true)
            this.map.getLayers().item(2).setVisible(true)
            break
        }
      }
    })
    // switch (type) {
    //   case 'vectorMap':
    //     /* this.getBaseLayer().forEach(item => {
    //        item.setVisible(true)
    //        item.setVisible(true)
    //        // this.map.addLayer(item)
    //      })*/
    //     this.map.getLayers().item(0).setVisible(true)
    //     this.map.getLayers().item(1).setVisible(true)
    //     this.map.getLayers().item(2).setVisible(false)
    //     this.map.getLayers().item(3).setVisible(false)
    //     break
    //   case 'imageMap':
    //     this.map.getLayers().item(0).setVisible(false)
    //     this.map.getLayers().item(1).setVisible(false)
    //     this.map.getLayers().item(2).setVisible(true)
    //     this.map.getLayers().item(3).setVisible(true)
    //     break
    // }
  }

  // 按最优级别显示某个范围或某个Geometry;
  fit(extentOrGeometry) {
    this.map.getView().fit(extentOrGeometry, this.map.getSize())
  }

  // 以最佳视图显示多个feature
  fitByFeatures(features) {
    if (features) {
      const extent = createEmpty()
      features.forEach((feature) => {
        extend(extent, feature.getGeometry().getExtent())
      })
      this.map.getView().fit(extent, this.map.getSize())
    }
  }

  saveHistoryViewExtent = (e) => {
    if (this.isAllowUpdateHistory) {
      const viewExtent = this.map.getView().calculateExtent(this.map.getSize())
      this.historyView.push(viewExtent)
      if (this.historyView.length > this.maxHistory) {
        this.historyView.splice(0, 1)
      }
      this.historyIndex = this.historyView.length - 1
    }
    this.isAllowUpdateHistory = true
  }

  // 前视图
  gotoPrevView() {
    if (this.historyView.length > 0) {
      --this.historyIndex
      if (this.historyIndex < 0) {
        this.historyIndex = 0
        return
      }
      // map.un('moveend', saveHistoryViewExtent);
      this.isAllowUpdateHistory = false
      this.fit(this.historyView[this.historyIndex])
    }
  }

  // 后视图
  gotoNextView() {
    if (this.historyView.length > 0) {
      ++this.historyIndex
      if (this.historyIndex >= this.historyView.length - 1) {
        this.historyIndex = this.historyView.length - 1
        return
      }
      // map.un('moveend', saveHistoryViewExtent);
      this.isAllowUpdateHistory = false
      this.fit(this.historyView[this.historyIndex])
    }
  }

  createFeatureLayer(opt) {
    return new TyFeatureLayer(opt)
  }

  // 以下方法是跟地图对象相关的
  getMap() {
    return this.map
  }

  getExtent() {
    return this.extent
  }

  getCenter() {
    return this.center
  }

  getResolutions() {
    return this.resolutions
  }

  /**
   * @Description 获取当前视野中心点
   * @Date 2019/11/20 17:48
   * @Author yuesheng.zhu@topevery.club
   */
  getViewCenter() {
    const view = this.map.getView()
    const mapExtent = view.calculateExtent(this.map.getSize())
    return getCenter(mapExtent)
  }

  // 放大
  zoomIn() {
    const view = this.map.getView()
    const zoom = view.getZoom()
    view.setZoom(zoom + 1)
  }

  // 缩小
  zoomOut() {
    const view = this.map.getView()
    const zoom = view.getZoom()
    view.setZoom(zoom - 1)
  }

  rest() {
    const view = this.map.getView()
    view.setCenter(this.center)
    view.setZoom(this.zoom)
  }

  ctrlAltA() {
    const view = this.map.getView()
    view.once('postcompose', function (event) {
      let canvas = event.context.canvas
      if (navigator.msSaveBlob) {
        navigator.msSaveBlob(canvas.msToBlob(), 'map.png')
      } else {
        canvas.toBlob(function (blob) {
          // FileSaverJS.saveAs(blob, "map.png");
        })
      }
    })
    this.map.renderSync()
  }

  // 缩放到全图
  zoomToFull() {
    this.fit(this.extent)
  }

  // 设置缩放级别
  setZoom(zoom) {
    this.map.getView().setZoom(zoom)
  }

  // 添加图层；
  addLayer(layer) {
    this.map.addLayer(layer)
  }

  // 删除图层；
  removeLayer(layer) {
    this.map.removeLayer(layer)
  }

  // 左移半屏
  moveToLeft() {
    const view = this.map.getView()
    const resolution = view.getResolution()
    const size = this.map.getSize()
    const center = view.getCenter()
    center[0] = center[0] - (size[0] * resolution) / 2
    view.setCenter(center)
  }

  // 右移半屏
  moveToRight() {
    const view = this.map.getView()
    const resolution = view.getResolution()
    const size = this.map.getSize()
    const center = view.getCenter()
    center[0] = center[0] + (size[0] * resolution) / 2
    view.setCenter(center)
  }

  // 上移半屏
  moveToUp() {
    const view = this.map.getView()
    const resolution = view.getResolution()
    const size = this.map.getSize()
    const center = view.getCenter()
    center[1] = center[1] - (size[1] * resolution) / 2
    view.setCenter(center)
  }

  // 下移半屏
  moveToDown() {
    const view = this.map.getView()
    const resolution = view.getResolution()
    const size = this.map.getSize()
    const center = view.getCenter()
    center[1] = center[1] + (size[1] * resolution) / 2
    view.setCenter(center)
  }

  // 获取一个点跑另一个点的方向
  getRotation(start, end) {
    const dx = end[0] - start[0]
    const dy = end[1] - start[1]
    const rotation = Math.atan2(dy, dx)
    return rotation
  }

  // 获取框选地图的feature
  getMapSelectInfo(extent) {
    /* this.map.getMap().getOverlays().forEach((item, index) => {
      console.log('>>>>>getOverlays>>>>', item)
			 })
    })*/
    const features = []
    const layers = this.map.getLayers()
    layers.forEach((item) => {
      const source = item.getProperties().source
      if ('getFeatures' in source) {
        source.forEachFeatureIntersectingExtent(extent, (feature) => {
          features.push(feature)
        })
      }
    })
    return features
  }

  // 开启坐标选择
  openPoint(Callback) {
    this.beforeCallback = Callback
    this.map.on('click', this.getPoint)
  }

  closePoint() {
    this.marker = null
    this.pointOption = {}
    this.map.un('click', this.getPoint)
  }

  getPoint = (event) => {
    if (this.beforeCallback) {
      this.beforeCallback(event.coordinate)
    }
    // this.getPointInfo(event, this.pointOption, this.pointOption.callback || null, this.pointOption.beforeCallback || null)
  }

  // 获取坐标详细信息
  getPointInfo(event, option, callback, beforeCallback) {
    // console.info(TyCoordinateConvert.gcj_decrypt(event.coordinate[0], event.coordinate[1]))
    // event.coordinate[0] = '114.057909'
    // event.coordinate[1] = '22.54368'
    // 12696300.276395936, 2577265.5012054304
    const showMarker = option.isShowMarker === undefined ? true : option.isShowMarker
    const remoteAddress = option.isRemoteAddress === undefined ? true : option.isRemoteAddress
    let coordinate = []
    // coordinate = transform(event.coordinate, 'EPSG:3857', 'EPSG:4326')
    coordinate = event.coordinate
    const pointInfo = {
      coordinate: event.coordinate
    }
    if (remoteAddress) {
      /* const url = `https://api.${this.tiandituUrl}/geocoder`
      const query = {
        // postStr: '{lon: ' + event.coordinate[0] + ', lat: ' + event.coordinate[1] + ', ver: 1}',
        postStr: `{lon:${coordinate[0]},lat:${coordinate[1]}, ver: 1}`,
        tk: this.secretKey
      }*/
      const p = TyCoordinateConvert.gcj_encrypt(coordinate[1], coordinate[0])
      var url = `https://${this.gaodeUrl}/v3/geocode/regeo`
      if (window.location.host === '23.211.94.50') {
        url = 'http://23.211.94.50/mapApi/regeo'
      }
      if (process.env.NODE_ENV === 'development') {
        url = 'http://23.211.94.50/mapApi/regeo'
      }
      const query = {
        // postStr: '{lon: ' + event.coordinate[0] + ', lat: ' + event.coordinate[1] + ', ver: 1}',
        output: 'json',
        location: `${p.lon},${p.lat}`,
        key: this.gaoMapKey,
        radius: 0,
        extensions: 'all'
      }
      $.ajax({
        async: false,
        url: url,
        data: query,
        type: 'GET',
        dataType: 'json',
        success: (result) => {
          console.info(result)
          if (result.status === 0) {
            alert('请求错误')
          } else {
            console.log('result', result)
            Object.assign(pointInfo, result.regeocode)
          }
        },
        error: (xhr, status, error) => {
        }
      })
    }

    option.coordinate = event.coordinate
    if (beforeCallback) {
      beforeCallback()
    }
    const marker = showMarker ? this.setPointMarker(option) : {}
    if (callback) {
      callback(pointInfo, marker, event)
    }
  }

  setPointMarker(option) {
    const morePoint = option.morePoint || false
    const stopEvent = option.stopEvent || false
    const animate = option.animate === undefined ? true : option.animate
    const callback = option.callback
    const icon = new TyIcon(option.icon || './image/map/loc-red.png', option)
    const label = option.title ? (new TyLabel(option.title, option)) : null
    const markerId = option.markerId || undefined
    const centerOffset = option.centerOffset || []
    let marker = this.marker
    if (morePoint === true) {
      marker = new TyMarker({
        icon: icon,
        label: label,
        id: markerId,
        stopEvent: stopEvent,
        offset: [-15, -40],
        position: option.coordinate
      })
    } else {
      if (marker === null) {
        this.marker = marker = new TyMarker({
          icon: icon,
          label: label,
          id: markerId,
          stopEvent: stopEvent,
          offset: [-15, -40],
          position: option.coordinate
        })
      }
    }
    // 创建信息窗口对象
    this.map.addOverlay(marker.createOverlay())
    if (option.content) {
      const popup = new TyPopup(option.content, option)
      marker.openPopup(this.map, popup)
    }
    marker.getOverlay().setPosition(option.coordinate)
    if (animate) {
      this.map.getView().animate({
        center: [option.coordinate[0] + (centerOffset[0] || 0), option.coordinate[1] + (centerOffset[0] || 0)],
        duration: 500
      })
    }
    if (callback) {
      marker.addEventListener('click', () => {
        callback(marker, option.data || {})
      })
    }
    return marker
  }

  /**
   * @Description 获取鼠标点击的图层
   * @Date 2019/11/18 15:05
   * @Author yuesheng.zhu@topevery.club
   */
  getClickFeature(event) {
    const pixel = this.map.getEventPixel(event.originalEvent)
    return this.map.forEachFeatureAtPixel(pixel, (feature) => {
      const features = feature.get('features') || null
      return features === null ? feature : features[0]
    })
  }

  // 获取行政区域
  getArea(name, callback) {
    const url = `https://${this.gaodeUrl}/v3/config/district`
    const query = {
      keywords: name,
      subdistrict: 0,
      key: this.gaoMapKey,
      extensions: 'all'
    }
    $.ajax({
      async: false,
      url: url,
      data: query,
      type: 'GET',
      dataType: 'json',
      success: (result) => {
        if (result.returncode === '101') {
          callback(null)
          // alert(result.msg)
        } else {
          const data = result.districts[0]
          const polyline = data.polyline.split('|')
          const areaPoints = new Array(polyline.length)
          polyline.forEach((points, index) => {
            const allPoints = points.split(';')
            const pointArray = []
            allPoints.forEach((point) => {
              const p = point.split(',')
              console.log('p', p)
              const pDecrypt = TyCoordinateConvert.gcj_decrypt(p[1], p[0])
              pointArray.push([pDecrypt.lon, pDecrypt.lat])
            })
            areaPoints[index] = pointArray
          })
          result.areaPoints = areaPoints
          callback(result)
          /* const data = result.data[0]
          const areaPoints = new Array(data.points.length)
          data.points.forEach((points, index) => {
            const allPoints = points.region.split(',')
            const pointArray = []
            allPoints.forEach((point) => {
              const p = point.split(' ')
              pointArray.push([p[0], p[1]])
            })
            areaPoints[index] = pointArray
          })
          result.data[0].areaPoints = areaPoints
          callback(result.data[0])*/
        }
      },
      error: (xhr, status, error) => {
      }
    })
  }

  getVersion() {
    return '1.2'
  }
}

export default TyMap
